package com.smedi.ismedi.cronjob.core.port.adapter.restful;

import com.smedi.ismedi.cronjob.api.dto.request.JobInfoRequest;
import com.smedi.ismedi.cronjob.api.dto.request.JobRunRequest;
import com.smedi.ismedi.cronjob.api.dto.response.JobInfoResponse;
import com.smedi.ismedi.cronjob.api.dto.response.JobRunResponse;
import com.smedi.ismedi.cronjob.api.feign.RemoteJobInfoFeignApi;
import com.smedi.ismedi.cronjob.api.feign.RemoteJobRunFeignApi;
import com.smedi.ismedi.cronjob.core.application.command.JobInfoCommand;
import com.smedi.ismedi.cronjob.core.application.command.JobRunCommand;
import com.smedi.ismedi.cronjob.core.application.service.JobApplicationService;
import com.smedi.ismedi.cronjob.core.domain.aggregatemodel.JobInfo;
import com.smedi.ismedi.cronjob.core.domain.aggregatemodel.JobRun;
import com.smedi.ismedi.web.starter.common.ResponseData;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.List;

@Slf4j
@RestController
@AllArgsConstructor
public class JobController implements RemoteJobInfoFeignApi, RemoteJobRunFeignApi {
    private final DozerUtil dozerUtil;

    private JobApplicationService jobApplicationService;

    @PostConstruct
    public void initialize() {
        try {
            log.info("init quartz");
            postRestartAllJob(null);
            log.info("init success");
        } catch (Exception e) {
            log.error("printStackTrace ", e);
        }
    }

    @Override
    public ResponseData<Boolean> postRunJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        return new ResponseData<>().success(jobApplicationService.runJob(jobInfoCommand));
    }

    @Override
    public ResponseData<Boolean> postPauseJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        return new ResponseData<>().success(jobApplicationService.pauseJob(jobInfoCommand));
    }

    @Override
    public ResponseData<Boolean> postResumeJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        return new ResponseData<>().success(jobApplicationService.resumeJob(jobInfoCommand));
    }

    @Override
    public ResponseData<Boolean> postRefreshJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        return new ResponseData<>().success(jobApplicationService.refreshJob(jobInfoCommand));
    }

    @Override
    public ResponseData<List<JobInfoResponse>> postRestartAllJob(JobInfoRequest jobInfoRequest) {
        List<JobInfo> jobInfos = jobApplicationService.restartAllJob();
        List<JobInfoResponse> jobInfoResponse = dozerUtil.convertor(jobInfos, JobInfoResponse.class);
        return new ResponseData<>().success(jobInfoResponse);
    }

    @Override
    public ResponseData<JobInfoResponse> postInsertJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        JobInfo jobInfo = jobApplicationService.insertJob(jobInfoCommand);
        return new ResponseData<>().success(dozerUtil.convertor(jobInfo, JobInfoResponse.class));
    }

    @Override
    public ResponseData<Boolean> postDeleteJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        return new ResponseData<>().success(jobApplicationService.deleteJob(jobInfoCommand));
    }

    @Override
    public ResponseData<JobInfoResponse> postUpdateJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        JobInfo jobInfo = jobApplicationService.updateJob(jobInfoCommand);
        JobInfoResponse jobInfoResponse = dozerUtil.convertor(jobInfo, JobInfoResponse.class);
        return new ResponseData<>().success(jobInfoResponse);
    }

    @Override
    public ResponseData<JobInfoResponse> postGetJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest,JobInfoCommand.class);
        JobInfo jobInfo = jobApplicationService.getJob(jobInfoCommand.getId());
        JobInfoResponse jobInfoResponse = dozerUtil.convertor(jobInfo, JobInfoResponse.class);
        return new ResponseData<>().success(jobInfoResponse);
    }

    @Override
    public ResponseData<List<JobInfoResponse>> postListJob(JobInfoRequest jobInfoRequest) {
        JobInfoCommand jobInfoCommand = dozerUtil.convertor(jobInfoRequest, JobInfoCommand.class);
        List<JobInfo> jobInfos = jobApplicationService.listJob(jobInfoCommand);
        List<JobInfoResponse> jobInfoResponse = dozerUtil.convertor(jobInfos, JobInfoResponse.class);
        return new ResponseData<>().success(jobInfoResponse);
    }

    @Override
    public ResponseData<JobRunResponse> postUpdateJobRun(JobRunRequest jobRunRequest) {
        JobRunCommand jobRunCommand = dozerUtil.convertor(jobRunRequest, JobRunCommand.class);
        JobRun jobRun = jobApplicationService.updateJobRun(jobRunCommand);
        return new ResponseData<>().success(dozerUtil.convertor(jobRun, JobRunResponse.class));
    }

    @Override
    public ResponseData<JobRunResponse> postGetJobRun(Long id) {
        JobRun jobRun = jobApplicationService.getJobRun(id);
        return new ResponseData<>().success(dozerUtil.convertor(jobRun, JobRunResponse.class));
    }

    @Override
    public ResponseData<List<JobRunResponse>> postListJobRun(JobRunRequest jobRunRequest) {
        JobRunCommand jobRunCommand = dozerUtil.convertor(jobRunRequest, JobRunCommand.class);
        List<JobRun> jobRuns = jobApplicationService.listJobRun(jobRunCommand);
        List<JobRunResponse> cronJobResponses = dozerUtil.convertor(jobRuns, JobRunResponse.class);
        return new ResponseData<>().success(cronJobResponses);
    }
}